﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ArrayHelper
{
    public static class ArrayHelper
    {
        public static T[] Add<T>(this T[] arr, T data)
        {
            if (data == null) throw new ArgumentNullException();
            T[] tmp = new T[arr.Length + 1];
            Array.Copy(arr, tmp, arr.Length);
            tmp[tmp.Length - 1] = data;
            return tmp;
        }
        public static T[] AddRange<T>(this T[] arr, T[] datas)
        {
            T[] tmp = new T[arr.Length + datas.Length];
            Array.Copy(arr, 0, tmp, 0, arr.Length);
            Array.Copy(datas, 0, tmp, arr.Length, datas.Length);
            return tmp;
        }
        public static T[] InsertAt<T>(this T[] arr, T data, int index)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (index < 0 || index >= arr.Length) throw new IndexOutOfRangeException();
            T[] tmp = new T[arr.Length + 1];
            Array.Copy(arr, 0, tmp, 0, index);
            tmp[index] = data;
            Array.Copy(arr, index, tmp, index + 1, arr.Length - index);
            return tmp;
        }
        public static T[] InsertRange<T>(this T[] arr, int index, T[] datas)
        {
            if (datas == null) throw new ArgumentNullException("data");
            if (index < 0 || index >= arr.Length) throw new IndexOutOfRangeException();
            T[] tmp = new T[arr.Length + datas.Length];
            Array.Copy(arr, 0, tmp, 0, index);
            Array.Copy(datas, 0, tmp, index, datas.Length);
            Array.Copy(arr, index, tmp, datas.Length + index + 1, arr.Length - index);
            return tmp;
        }
        public static T[] RemoveAt<T>(this T[] arr, int index)
        {
            if (index < 0 || index >= arr.Length) throw new IndexOutOfRangeException();
            T[] tmp = new T[arr.Length - 1];
            if (index > 0)
                Array.Copy(arr, 0, tmp, 0, index);
            if (index < arr.Length - 1)
                Array.Copy(arr, index + 1, tmp, index, arr.Length - index - 1);
            return tmp;
        }
        public static T[] RemoveRange<T>(this T[] arr, int startIndex, int count)
        {
            if (startIndex < 0 || (startIndex + count - 1) >= arr.Length) throw new IndexOutOfRangeException();
            T[] tmp = new T[arr.Length - count];
            Array.Copy(arr, 0, tmp, startIndex - 1, startIndex);
            Array.Copy(arr, startIndex + count, tmp, startIndex, arr.Length - startIndex - count);
            return tmp;
        }

        public static bool IsDuplicat<T>(this T[] arr, T data)
        {
            if (data == null) throw new ArgumentNullException("data");
            bool b = default(bool);
            foreach (T item in arr)
                if (item.Equals(data))
                {
                    b = true;
                    break;
                }
            return b;
        }

        public static T[] Suffle<T>(this T[] arr)
        {
            if (arr == null) throw new NullReferenceException();
            if (arr.Length == 0) throw new Exception("0 Length Array");
            T[] res = arr;
            Random rd = new Random();
            int n = res.Length;
            for (int i = 0; i < n; i++)
            {
                int r = i + (int)(rd.NextDouble() * (n - i));
                T t = res[r];
                res[r] = res[i];
                res[i] = t;
            }
            return res;
        }

    }
}